<?php

/**
 * This is the model class for table "menu".
 *
 * The followings are the available columns in table 'menu':
 * @property integer $id
 * @property integer $sort
 * @property integer $pid
 * @property string $type
 * @property string $auth
 * @property string $name
 * @property string $url
 * @property string $target
 * @property string $css_class
 * @property string $icon
 * @property string $status
 * @property string $remark
 *
 * The followings are the available model relations:
 * @property Role[] $roles
 */
class Menu extends CActiveRecord
{
    const STATUS_NORMAL = 'normal';
    const STATUS_DISABLE = 'disable';

    const TYPE_TOP = 'top';
    const TYPE_BANNER = 'banner';

    const AUTH_UNLOGIN = 'unlogin';
    const AUTH_LOGIN = 'login';
    const AUTH_ALL = 'all';

    const TARGET_BLANK = '_blank';
    const TARGET_SELF = '_self';

    public $searchKey = '';

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'menu';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('sort, pid, type, auth, name, url, status', 'required'),
            array('sort, pid', 'numerical', 'integerOnly' => true),
            array('type, auth, target, icon, css_class, status', 'length', 'max' => 32),
            array('name, url', 'length', 'max' => 256),
            array('remark', 'length', 'max' => 1024),
            array('searchKey', 'safe'),
            // The following rule is used by search().
            // @todo Please remove those attributes that should not be searched.
            array('id, sort, pid, type, auth, name, url, target, icon, css_class, status, remark', 'safe', 'on' => 'search'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            'subs' => array(self::HAS_MANY, 'Menu', 'pid'),
            'roles' => array(self::MANY_MANY, 'Role', 'role_menu(mid, rid)'),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'ID',
            'sort' => '排序',
            'pid' => '父菜单',
            'type' => '类型',
            'auth' => '授权',
            'name' => '名称',
            'url' => '地址',
            'target' => '目标',
            'icon' => '图标',
            'css_class' => 'Css样式',
            'status' => '状态',
            'remark' => '备注',
            'searchKey' => '搜索关键词',
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     *
     * Typical usecase:
     * - Initialize the model fields with values from filter form.
     * - Execute this method to get CActiveDataProvider instance which will filter
     * models according to data in model fields.
     * - Pass data provider to CGridView, CListView or any similar widget.
     *
     * @return CActiveDataProvider the data provider that can return the models
     * based on the search/filter conditions.
     */
    public function search()
    {
        // @todo Please modify the following code to remove attributes that should not be searched.

        $criteria = new CDbCriteria;

        $criteria->compare('id', $this->id);
        $criteria->compare('sort', $this->sort);
        $criteria->compare('pid', $this->pid);
        $criteria->compare('type', $this->type, true);
        $criteria->compare('auth', $this->auth, true);
        $criteria->compare('name', $this->name, true);
        $criteria->compare('url', $this->url, true);
        $criteria->compare('target', $this->target, true);
        $criteria->compare('icon', $this->icon, true);
        $criteria->compare('css_class', $this->css_class, true);
        $criteria->compare('status', $this->status, true);
        $criteria->compare('remark', $this->remark, true);

        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
        ));
    }

    public function searchByKey()
    {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.
        $criteria = new CDbCriteria;
        //屏蔽admin
        if ($this->searchKey !== '') {
            $criteria->addSearchCondition('name', $this->searchKey, true, 'OR');
            $criteria->addSearchCondition('url', $this->searchKey, true, 'OR');
            $criteria->addSearchCondition('type', $this->searchKey, true, 'OR');
            $criteria->addSearchCondition('target', $this->searchKey, true, 'OR');
            $criteria->addSearchCondition('status', $this->searchKey, true, 'OR');
            $criteria->addSearchCondition('remark', $this->searchKey, true, 'OR');
        }
        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
        ));
    }

    /**
     * Returns the static model of the specified AR class.
     * Please note that you should have this exact method in all your CActiveRecord descendants!
     * @param string $className active record class name.
     * @return Menu the static model class
     */
    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }

    public static function getMenuTree($inputName = '', $inputId = '', $on = array(), $htmlOptions = array())
    {
        $menuTree = array(
            self::TYPE_BANNER => array(),
            self::TYPE_TOP => array(),
        );
        $pars = self::model()->findAll(array(
            'condition' => 'pid = 0 AND (auth = :auth_login OR auth = :auth_all)',
            'params' => array(':auth_login' => self::AUTH_LOGIN, ':auth_all' => self::AUTH_ALL),
            'order' => 'sort ASC',
        ));
        foreach ($pars as $par) {
            $relTree[$par->id]['name'] = $par->name;
            $relTree[$par->id]['type'] = $par->type;
            $relTree[$par->id]['status'] = $par->status;
            $relTree[$par->id]['subs'] = array();
        }
        $subs = self::model()->findAll(array(
            'condition' => 'pid != 0',
            'order' => 'sort ASC',
        ));
        foreach ($subs as $sub) {
            if (isset($relTree[$sub->pid])) {
                $relTree[$sub->pid]['subs'][$sub->id]['name'] = $sub->name;
                $relTree[$sub->pid]['subs'][$sub->id]['type'] = $sub->type;
                $relTree[$sub->pid]['subs'][$sub->id]['status'] = $sub->status;
            }
        }
        foreach ($pars as $par) {
            if (isset($menuTree[$par->type])) {
                $menuTree[$par->type][$par->id] = $relTree[$par->id];
            }
        }
        $element = '';
        $element .= '<div id="role_menu_tree">';
        $map_type = self::getOptions('type');
        foreach ($menuTree as $type => $typeMenus) {
            $element .= '<blockquote style="margin:3px 0;"><b>' . (empty($map_type[$type]) ? ucfirst($type) . ' Menu List' : $map_type[$type]) . '</b></blockquote>';
            foreach ($typeMenus as $parId => $parNode) {
                $element .= '<div class="tree-branch" style="padding-left:20px;">';
                $element .= '<div class="checkbox">';
                $element .= '<label>';
                $element .= CHtml::checkBox($inputName, in_array($parId, $on), array('id' => $inputId . '_par', 'value' => $parId, 'class' => 'par_perm', 'disabled' => (isset($htmlOptions['disabled']))));
                $element .= '<a class="tree-branch-master" href="javascript:void(0)"><i class="fa fa-gears"></i>' . $parNode['name'] . '</a>';
                $element .= '</label>';
                $element .= '</div>';
                if (!empty($parNode['subs'])) {
                    $element .= '<div class="tree-branch-subs" style="padding-left:20px;">';
                    foreach ($parNode['subs'] as $subId => $subNode) {
                        $element .= '<div class="checkbox">';
                        $element .= '<label>';
                        $element .= CHtml::checkBox($inputName, in_array($subId, $on), array('id' => $inputId . '_par', 'value' => $subId, 'class' => 'par_perm', 'disabled' => (isset($htmlOptions['disabled']))));
                        $element .= '<a href="javascript:void(0)"><i class="fa fa-gear"></i>' . $subNode['name'] . '</a>';
                        $element .= '</label>';
                        $element .= '</div>';
                    }
                    $element .= '</div>';
                }
                $element .= '</div>';

            }
        }
        $element .= '</div>';
        $element .= '<script type="text/javascript">';
        $element .= '$(function($) {';
        $element .= '	$("#role_menu_tree a.tree-branch-master").click(function(e){';
        $element .= '		$(this).parents(".tree-branch").children(".tree-branch-subs").toggle("fast");';
        $element .= '	});';
        $element .= '});';
        $element .= '</script>';
        return $element;
    }

    public static function getMenus($type = self::TYPE_BANNER)
    {
        $menus = array();
        if (Yii::app()->user->isGuest) {
            switch ($type) {
                case self::TYPE_BANNER:
                    $menus = Menu::model()->findAll(array(
                        'condition' => 'type = :type AND (auth = :auth_unlogin OR auth = :auth_all)',
                        'order' => 'sort ASC',
                        'params' => array(':type' => self::TYPE_BANNER, ':auth_unlogin' => self::AUTH_UNLOGIN, ':auth_all' => self::AUTH_ALL),
                    ));
                    break;
                case self::TYPE_TOP:
                    $menus = Menu::model()->findAll(array(
                        'condition' => 'type = :type AND (auth = :auth_unlogin OR auth = :auth_all)',
                        'order' => 'sort ASC',
                        'params' => array(':type' => self::TYPE_TOP, ':auth_unlogin' => self::AUTH_UNLOGIN, ':auth_all' => self::AUTH_ALL),
                    ));
                    break;
            }
        } else {
            if (Yii::app()->user->isAdmin()) {
                switch ($type) {
                    case self::TYPE_BANNER:
                    case self::TYPE_TOP:
                        $menus = Menu::model()->findAll(array(
                            'condition' => 'type = :type AND (auth = :auth_login OR auth = :auth_all)',
                            'order' => 'sort ASC',
                            'params' => array(':type' => $type, ':auth_login' => self::AUTH_LOGIN, ':auth_all' => self::AUTH_ALL),
                        ));
                        break;
                }
            } else {
                $rid = Yii::app()->user->getState('rid');
                switch ($type) {
                    case self::TYPE_BANNER:
                    case self::TYPE_TOP:
                        $menus = Menu::model()->findAll(array(
                            'select' => 't.*',
                            'join' => 'LEFT JOIN role_menu rm ON rm.mid = t.id',
                            'condition' => 't.type = :type AND rm.rid = :rid AND (auth = :auth_login OR auth = :auth_all)',
                            'order' => 'sort ASC',
                            'params' => array(':type' => $type, ':rid' => $rid, ':auth_login' => self::AUTH_LOGIN, ':auth_all' => self::AUTH_ALL),
                        ));
                        break;
                }
            }
        }
        return $menus;
    }

    public static function getOptions($attribute = '')
    {
        $options = array();
        switch ($attribute) {
            case 'status':
                $options = array(
                    self::STATUS_NORMAL => self::STATUS_NORMAL,
                    self::STATUS_DISABLE => self::STATUS_DISABLE,
                );
                break;
            case 'type':
                $options = array(
                    self::TYPE_BANNER => '主菜单',
                    self::TYPE_TOP => '下拉菜单',
                );
                break;
            case 'auth':
                $options = array(
                    self::AUTH_ALL => self::AUTH_ALL,
                    self::AUTH_LOGIN => self::AUTH_LOGIN,
                    self::AUTH_UNLOGIN => self::AUTH_UNLOGIN,
                );
                break;
            case 'target':
                $options = array(
                    self::TARGET_SELF => self::TARGET_SELF,
                    self::TARGET_BLANK => self::TARGET_BLANK,
                );
                break;
            case 'pid':
                $options[0] = '==========';
                $pars = self::model()->findAllByAttributes(array('pid' => 0));
                foreach ($pars as $par) {
                    $options[$par->id] = $par->name;
                }
                break;
        }
        return $options;
    }

}
